import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ClothingQueue {
    ArrayList<Integer> topQueue;
    ArrayList<Integer> dirtyTops;
    Map<Integer, Top> mapToTops;

    /**
     * Main function.
     * 
     */
    public static void main(String[] args) throws IOException {
        ClothingQueue queue = new ClothingQueue();
        queue.loadTops();
        Outfit chosenOutfit = queue.findAppropriateTop();

        int topId = chosenOutfit.primaryTopId;
        int matchId = chosenOutfit.secondaryTopId;

        if (queue.mapToTops.containsKey(topId)) {
            Top chosen = queue.mapToTops.get(topId);
            chosen.printShortInformation();

            if (queue.mapToTops.containsKey(matchId)) {
                Top match = queue.mapToTops.get(matchId);
                match.printShortInformation();
            }
        } else {
            System.out.println("Sorry, no valid shirts were found.");
        }
        /*
         * if (queue.mapToTops.containsKey(id)) { Top chosen =
         * queue.mapToTops.get(id); chosen.printShortInformation(); } else {
         * System.out.println("Sorry, no valid shirts were found."); }
         */
    }

    /**
     * ClothingQueue.load() Loads the data from the files.
     * 
     * @throws IOException
     */
    public void loadTops() throws IOException {
        this.topQueue = new ArrayList<Integer>();
        this.mapToTops = new HashMap<Integer, Top>();
        this.dirtyTops = new ArrayList<Integer>();

        /*
         * Input the clean queue.
         */
        BufferedReader queueList = new BufferedReader(new FileReader(
                "data/tops/queue.txt"));

        int numberOfCleanTops = this.getNumberOfTops("data/tops/clean.txt");

        int index;
        for (index = 0; index < numberOfCleanTops; index++) {
            String thisId = queueList.readLine();
            this.topQueue.add(Integer.valueOf(thisId));
            Top thisTop = new Top("data/tops/top" + thisId + ".txt");
            this.mapToTops.put(Integer.valueOf(thisId), thisTop);
        }

        queueList.close();

        /*
         * Input the dirty list.
         */
        BufferedReader dirtyList = new BufferedReader(new FileReader(
                "data/tops/dirty.txt"));
        for (index = 0; index < (this.getNumberOfTops("data/tops/guide.txt") - numberOfCleanTops); index++) {
            String thisId = dirtyList.readLine();
            this.dirtyTops.add(Integer.valueOf(thisId));
            Top thisTop = new Top("data/tops/top" + thisId + ".txt");
            this.mapToTops.put(Integer.valueOf(thisId), thisTop);
        }

        dirtyList.close();
    }

    /**
     * ClothingQueue.print() Prints the data.
     * 
     * @throws IOException
     */
    public void print() throws IOException {
        for (Integer id : this.topQueue) {
            Top thisTop = this.mapToTops.get(id);
            thisTop.printShortInformation();
        }
    }

    public Outfit findAppropriateTop() throws NumberFormatException,
            IOException {
        Outfit thisOutfit = new Outfit();

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("High temp for today: ");
        int high = Integer.parseInt(in.readLine());
        System.out.println("Formality for today: ");
        System.out.println("0 - special event, hanging out");
        System.out.println("1 - daily, casual");
        System.out.println("2 - formal");
        System.out.println("3 - extremely formal");
        int formality = Integer.parseInt(in.readLine());
        int low = high - 20;
        int chosenId = -1;
        int matchId = -1;

        if (high > 85) {
            high = 85;
        }

        if (high > 45) {
            for (Integer id : this.topQueue) {
                Top thisTop = this.mapToTops.get(id);
                int topMin = thisTop.minimumTemperature;
                int topFormality = thisTop.formality;
                int topId = thisTop.idNumber;
                if ((topMin < high && topMin >= low)
                        && ((formality == 0 && (topFormality == 0
                                || topFormality == 1 || topFormality == 2))
                                || (formality == 1 && (topFormality == 1 || topFormality == 2))
                                || (formality == 2 && (topFormality == 2)) || (formality == 3 && (topFormality == 2 || topFormality == 3)))) {
                    if (thisTop.needsMatch == false) {
                        chosenId = topId;
                        break;
                    } else {
                        matchId = this.findMatch(topId, high);

                        if (matchId > 0) {
                            chosenId = topId;
                            break;
                        }
                    }
                } else if (topMin >= high) {
                    matchId = this.findMatch(topId, high);

                    if (matchId > 0) {
                        break;
                    }
                }
            }
        } else {
            for (Integer id : this.topQueue) {
                Top thisTop = this.mapToTops.get(id);
                if (thisTop.needsMatch) {

                }
            }
        }

        thisOutfit.primaryTopId = chosenId;
        thisOutfit.secondaryTopId = matchId;

        return thisOutfit;
    }

    int getNumberOfTops(String fileName) throws NumberFormatException,
            IOException {
        BufferedReader guide = new BufferedReader(new FileReader(fileName));
        int numberOfTops = Integer.parseInt(guide.readLine());
        guide.close();

        return numberOfTops;
    }

    /**
     * Adds a top to the end of the queue.
     * 
     * @throws IOException
     */
    public void addTopToCollection() throws IOException {
        BufferedReader consoleIn = new BufferedReader(new InputStreamReader(
                System.in));
        Top thisTop = new Top(consoleIn,
                this.getNumberOfTops("data/tops/guide.txt"));
        String fileName = "data/tops/top" + thisTop.idNumber + ".txt";

        PrintWriter guidePrint = new PrintWriter(new FileWriter(
                "data/tops/guide.txt"));
        int newNumberOfTops = thisTop.idNumber + 1;
        guidePrint.println(newNumberOfTops);
        guidePrint.close();

        PrintWriter queueList = new PrintWriter(new BufferedWriter(
                new FileWriter("data/tops/queue.txt", true)));
        queueList.println(thisTop.idNumber);
        queueList.close();

        thisTop.printInformationWithoutNames(fileName);
        thisTop.printInformation();
    }

    public int findMatch(int topId, int maxTemp) {
        int matchId = -1;

        Top thisTop = this.mapToTops.get(topId);
        int topMinTemp = thisTop.minimumTemperature;

        for (int id : thisTop.topMatchIds) {
            if (this.mapToTops.containsKey(id)) {
                Top potentialMatch = this.mapToTops.get(id);
                int matchAddTemp = 80 - potentialMatch.minimumTemperature;
                int fakeMaxTemp = maxTemp + matchAddTemp;
                int fakeMinTemp = fakeMaxTemp - 20;
                if (topMinTemp < fakeMaxTemp && topMinTemp > fakeMinTemp) {
                    matchId = id;
                    break;
                }
            }
        }

        return matchId;
    }
}
